home *** CD-ROM | disk | FTP | other *** search
- //***********************************************************************
- //
- // DlgCalc.cpp
- //
- //***********************************************************************
-
- #include <afxwin.h>
- #include <math.h>
- #include "Resource.h"
- #include "DlgCalc.h"
-
- #define MAXCHARS 22
-
- CMyApp myApp;
-
- /////////////////////////////////////////////////////////////////////////
- // CMyApp member functions
-
- BOOL CMyApp::InitInstance ()
- {
- m_pMainWnd = new CCalcDialog;
- m_pMainWnd->ShowWindow (m_nCmdShow);
- m_pMainWnd->UpdateWindow ();
- return TRUE;
- }
-
- /////////////////////////////////////////////////////////////////////////
- // CCalcDialog message map and member functions
-
- BEGIN_MESSAGE_MAP (CCalcDialog, CDialog)
- ON_WM_PAINT ()
- ON_WM_SYSCOMMAND ()
- ON_CONTROL_RANGE (BN_CLICKED, IDC_0, IDC_9, OnDigit)
- ON_BN_CLICKED (IDC_ADD, OnAdd)
- ON_BN_CLICKED (IDC_SUBTRACT, OnSubtract)
- ON_BN_CLICKED (IDC_MULTIPLY, OnMultiply)
- ON_BN_CLICKED (IDC_DIVIDE, OnDivide)
- ON_BN_CLICKED (IDC_ENTER, OnEnter)
- ON_BN_CLICKED (IDC_CHGSIGN, OnChangeSign)
- ON_BN_CLICKED (IDC_EXP, OnExponent)
- ON_BN_CLICKED (IDC_STO, OnStore)
- ON_BN_CLICKED (IDC_RCL, OnRecall)
- ON_BN_CLICKED (IDC_FIX, OnFix)
- ON_BN_CLICKED (IDC_CLX, OnClear)
- ON_BN_CLICKED (IDC_DECIMAL, OnDecimal)
- ON_BN_CLICKED (IDC_DEL, OnDelete)
- END_MESSAGE_MAP ()
-
- CCalcDialog::CCalcDialog ()
- {
- for (int i=0; i<4; i++)
- m_dbStack[i] = 0.0;
-
- m_dbMemory = 0.0;
- m_strFormat = "%0.2f";
- m_bFixPending = FALSE;
- m_bErrorFlag = FALSE;
- m_bDecimalInString = FALSE;
- m_bStackLiftEnabled = FALSE;
- m_bNewX = TRUE;
-
- Create (IDD_CALCDLG);
- m_hAccel = ::LoadAccelerators (AfxGetInstanceHandle (),
- MAKEINTRESOURCE (IDR_CALCDLG));
-
- SetIcon (myApp.LoadIcon (IDI_CALCDLG), TRUE);
- }
-
- void CCalcDialog::OnCancel ()
- {
- DestroyWindow ();
- }
-
- void CCalcDialog::PostNcDestroy ()
- {
- delete this;
- }
-
- BOOL CCalcDialog::PreTranslateMessage (MSG* pMsg)
- {
- if (m_hAccel != NULL)
- if (::TranslateAccelerator (m_hWnd, m_hAccel, pMsg))
- return TRUE;
-
- return CDialog::PreTranslateMessage (pMsg);
- }
-
- BOOL CCalcDialog::OnInitDialog ()
- {
- CDialog::OnInitDialog ();
-
- CMenu* pMenu = GetSystemMenu (FALSE);
- pMenu->DeleteMenu (SC_SIZE, MF_BYCOMMAND);
- pMenu->DeleteMenu (SC_MAXIMIZE, MF_BYCOMMAND);
- pMenu->AppendMenu (MF_SEPARATOR);
- pMenu->AppendMenu (MF_STRING, IDM_SYSMENU_ABOUT,
- "&About DlgCalc...");
-
- CStatic* pRect = (CStatic*) GetDlgItem (IDC_DISPLAYRECT);
- pRect->GetWindowRect (&m_rect);
- pRect->DestroyWindow ();
- ScreenToClient (&m_rect);
-
- TEXTMETRIC tm;
- CClientDC dc (this);
- dc.GetTextMetrics (&tm);
- m_cxChar = tm.tmAveCharWidth;
- m_cyChar = tm.tmHeight - tm.tmDescent;
-
- DisplayXRegister ();
- return TRUE;
- }
-
- void CCalcDialog::OnSysCommand (UINT nID, LPARAM lParam)
- {
- if ((nID & 0xFFF0) == IDM_SYSMENU_ABOUT) {
- CAboutDialog dlg (this);
- dlg.DoModal ();
- return;
- }
- CDialog::OnSysCommand (nID, lParam);
- }
-
- void CCalcDialog::OnPaint ()
- {
- CPaintDC dc (this);
- dc.DrawEdge (m_rect, EDGE_SUNKEN, BF_RECT);
- UpdateDisplay (m_strDisplay);
- }
-
- BOOL CCalcDialog::OnCommand (WPARAM wParam, LPARAM lParam)
- {
- int nID = (int) LOWORD (wParam);
-
- if (m_bErrorFlag && (nID != IDC_CLX)) {
- ::MessageBeep (MB_ICONASTERISK);
- return TRUE;
- }
-
- if (m_bFixPending &&
- ((nID < IDC_0) || (nID > IDC_9)) &&
- (nID != IDC_CLX)) {
- ::MessageBeep (MB_ICONASTERISK);
- return TRUE;
- }
- return CDialog::OnCommand (wParam, lParam);
- }
-
- void CCalcDialog::OnDigit (UINT nID)
- {
- char cDigit = (char) nID;
-
- if (m_bFixPending) {
- m_strFormat.SetAt (3, cDigit - IDC_0 + 0x30);
- DisplayXRegister ();
- m_bFixPending = FALSE;
- m_bStackLiftEnabled = TRUE;
- m_bNewX = TRUE;
- return;
- }
-
- if (m_bNewX) {
- m_bNewX = FALSE;
- if (m_bStackLiftEnabled) {
- m_bStackLiftEnabled = FALSE;
- LiftStack ();
- }
- m_bDecimalInString = FALSE;
- m_strDisplay.Empty ();
- }
-
- int nLength = m_strDisplay.GetLength ();
- if ((nLength == MAXCHARS) ||
- ((nLength == (MAXCHARS - 10)) && !m_bDecimalInString))
- ::MessageBeep (MB_ICONASTERISK);
- else {
- m_strDisplay += (cDigit - IDC_0 + 0x30);
- UpdateDisplay (m_strDisplay);
- m_dbStack[0] = strtod (m_strDisplay.GetBuffer (0), NULL);
- }
- }
-
- void CCalcDialog::OnAdd ()
- {
- m_dbStack[0] += m_dbStack[1];
- DisplayXRegister ();
- DropStack ();
- m_bStackLiftEnabled = TRUE;
- m_bNewX = TRUE;
- }
-
- void CCalcDialog::OnSubtract ()
- {
- m_dbStack[0] = m_dbStack[1] - m_dbStack[0];
- DisplayXRegister ();
- DropStack ();
- m_bStackLiftEnabled = TRUE;
- m_bNewX = TRUE;
- }
-
- void CCalcDialog::OnMultiply ()
- {
- m_dbStack[0] *= m_dbStack[1];
- DisplayXRegister ();
- DropStack ();
- m_bStackLiftEnabled = TRUE;
- m_bNewX = TRUE;
- }
-
- void CCalcDialog::OnDivide ()
- {
- if (m_dbStack[0] == 0.0) {
- m_bErrorFlag = TRUE;
- ::MessageBeep (MB_ICONASTERISK);
- UpdateDisplay (CString ("Divide by zero error"));
- }
- else {
- m_dbStack[0] = m_dbStack[1] / m_dbStack[0];
- DisplayXRegister ();
- DropStack ();
- m_bStackLiftEnabled = TRUE;
- m_bNewX = TRUE;
- }
- }
-
- void CCalcDialog::OnEnter ()
- {
- LiftStack ();
- DisplayXRegister ();
- m_bStackLiftEnabled = FALSE;
- m_bNewX = TRUE;
- }
-
- void CCalcDialog::OnChangeSign ()
- {
- if (m_dbStack[0] != 0.0) {
- m_dbStack[0] = -m_dbStack[0];
- if (m_strDisplay[0] == '-') {
- int nLength = m_strDisplay.GetLength ();
- m_strDisplay = m_strDisplay.Right (nLength - 1);
- }
- else
- m_strDisplay = "-" + m_strDisplay;
- UpdateDisplay (m_strDisplay);
- }
- }
-
- void CCalcDialog::OnExponent ()
- {
- if (((m_dbStack[1] == 0.0) && (m_dbStack[0] < 0.0)) ||
- ((m_dbStack[1] == 0.0) && (m_dbStack[0] == 0.0)) ||
- ((m_dbStack[1] < 0.0) &&
- (floor (m_dbStack[0]) != m_dbStack[0]))) {
- m_bErrorFlag = TRUE;
- ::MessageBeep (MB_ICONASTERISK);
- UpdateDisplay (CString ("Invalid operation error"));
- }
- else {
- m_dbStack[0] = pow (m_dbStack[1], m_dbStack[0]);
- DisplayXRegister ();
- DropStack ();
- m_bStackLiftEnabled = TRUE;
- m_bNewX = TRUE;
- }
- }
-
- void CCalcDialog::OnStore ()
- {
- DisplayXRegister ();
- m_dbMemory = m_dbStack[0];
- m_bStackLiftEnabled = TRUE;
- m_bNewX = TRUE;
- }
-
- void CCalcDialog::OnRecall ()
- {
- LiftStack ();
- m_dbStack[0] = m_dbMemory;
- DisplayXRegister ();
- m_bStackLiftEnabled = TRUE;
- m_bNewX = TRUE;
- }
-
- void CCalcDialog::OnFix ()
- {
- m_bFixPending = TRUE;
- }
-
- void CCalcDialog::OnClear ()
- {
- if (m_bFixPending) {
- m_bFixPending = FALSE;
- return;
- }
-
- m_bErrorFlag = FALSE;
- m_dbStack[0] = 0.0;
- DisplayXRegister ();
- m_bStackLiftEnabled = FALSE;
- m_bNewX = TRUE;
- }
-
- void CCalcDialog::OnDecimal ()
- {
- if (m_bNewX) {
- m_bNewX = FALSE;
- if (m_bStackLiftEnabled) {
- m_bStackLiftEnabled = FALSE;
- LiftStack ();
- }
- m_bDecimalInString = FALSE;
- m_strDisplay.Empty ();
- }
-
- int nLength = m_strDisplay.GetLength ();
- if ((nLength == MAXCHARS) || (m_bDecimalInString))
- ::MessageBeep (MB_ICONASTERISK);
- else {
- m_bDecimalInString = TRUE;
- m_strDisplay += (char) 0x2E;
- UpdateDisplay (m_strDisplay);
- m_dbStack[0] = strtod (m_strDisplay.GetBuffer (0), NULL);
- }
- }
-
- void CCalcDialog::OnDelete ()
- {
- int nLength = m_strDisplay.GetLength ();
-
- if (!m_bNewX && (nLength != 0)) {
- if (m_strDisplay[nLength - 1] == '.')
- m_bDecimalInString = FALSE;
- m_strDisplay = m_strDisplay.Left (nLength - 1);
- UpdateDisplay (m_strDisplay);
- m_dbStack[0] = strtod (m_strDisplay.GetBuffer (0), NULL);
- }
- }
-
- void CCalcDialog::LiftStack ()
- {
- for (int i=3; i>0; i--)
- m_dbStack[i] = m_dbStack[i-1];
- }
-
- void CCalcDialog::DropStack ()
- {
- for (int i=1; i<3; i++)
- m_dbStack[i] = m_dbStack[i+1];
- }
-
- void CCalcDialog::DisplayXRegister ()
- {
- double dbVal = m_dbStack[0];
-
- if ((dbVal >= 1000000000000.0) || (dbVal <= -1000000000000.0)) {
- UpdateDisplay (CString ("Overflow error"));
- m_bErrorFlag = TRUE;
- MessageBeep (MB_ICONASTERISK);
- }
- else {
- m_strDisplay.Format (m_strFormat, dbVal);
- UpdateDisplay (m_strDisplay);
- }
- }
-
- void CCalcDialog::UpdateDisplay (CString& string)
- {
- CClientDC dc (this);
- CFont* pOldFont = dc.SelectObject (GetFont ());
- CSize size = dc.GetTextExtent (string);
-
- CRect rect = m_rect;
- rect.InflateRect (-2, -2);
- int x = rect.right - size.cx - m_cxChar;
- int y = rect.top + ((rect.Height () - m_cyChar) / 2);
-
- dc.ExtTextOut (x, y, ETO_OPAQUE, rect, string, NULL);
- dc.SelectObject (pOldFont);
- }
-
- /////////////////////////////////////////////////////////////////////////
- // CAboutDialog message map and member functions
-
- BEGIN_MESSAGE_MAP (CAboutDialog, CDialog)
- ON_WM_PAINT ()
- END_MESSAGE_MAP ()
-
- BOOL CAboutDialog::OnInitDialog ()
- {
- CDialog::OnInitDialog ();
-
- CStatic* pStatic = (CStatic*) GetDlgItem (IDC_ICONRECT);
- pStatic->GetWindowRect (&m_rect);
- pStatic->DestroyWindow ();
- ScreenToClient (&m_rect);
-
- return TRUE;
- }
-
- void CAboutDialog::OnPaint ()
- {
- CPaintDC dc (this);
- HICON hIcon = AfxGetMainWnd ()->GetIcon (TRUE);
-
- if (hIcon != NULL) {
- CDC dcMem;
- dcMem.CreateCompatibleDC (&dc);
-
- CBitmap bitmap;
- bitmap.CreateCompatibleBitmap (&dc, 32, 32);
- CBitmap* pOldBitmap = dcMem.SelectObject (&bitmap);
-
- CBrush brush (::GetSysColor (COLOR_3DFACE));
- dcMem.FillRect (CRect (0, 0, 32, 32), &brush);
- dcMem.DrawIcon (0, 0, hIcon);
-
- dc.StretchBlt (m_rect.left, m_rect.top, m_rect.Width(),
- m_rect.Height (), &dcMem, 0, 0, 32, 32, SRCCOPY);
-
- dcMem.SelectObject (pOldBitmap);
- }
- }
-